# @FileName  : tcp.py
# @Time      : 2023/7/7 0010  11:44
# @Author    : LuZhaoHui
# @Software  : PyCharm

from PyQt5.QtCore import *
from PyQt5.QtNetwork import *

# Tcp Server

SIZEOF_UINT16 = 6

class tcpThread(QThread):
    update_item = pyqtSignal(list)

    def __init__(self, socketId):
        super().__init__()
        self.socketId = socketId

    def run(self):
        socket = QTcpSocket()
        if not socket.setSocketDescriptor(self.socketId):
            # self.emit(SIGNAL("error(int)"), socket.error())
            self.error.connect(socket.error)
            return
        while socket.state() == QAbstractSocket.ConnectedState:
            nextBlockSize = 0
            stream = QDataStream(socket)
            stream.setVersion(QDataStream.Qt_5_7)
            if (socket.waitForReadyRead() and
                    socket.bytesAvailable() >= SIZEOF_UINT16):
                nextBlockSize = stream.readUInt16()
            else:
                self.sendError(socket, "Cannot read client request")
                return
            if socket.bytesAvailable() < nextBlockSize:
                if (not socket.waitForReadyRead(60000) or
                        socket.bytesAvailable() < nextBlockSize):
                    self.sendError(socket, "Cannot read client data")
                    return
            action = stream.readQString()
            # proc data
            print(action)
            # socket.waitForDisconnected()
            # try:
            #     Thread.lock.lockForRead()
            #     printBookings()
            # finally:
            #     Thread.lock.unlock()

    def sendError(self, socket, msg):
        reply = QByteArray()
        stream = QDataStream(reply, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_5_7)
        stream.writeUInt16(0)
        stream.writeQString("ERROR")
        stream.writeQString(msg)
        stream.device().seek(0)
        stream.writeUInt16(reply.size() - SIZEOF_UINT16)
        socket.write(reply)

    def sendReply(self, socket, action, room, date):
        reply = QByteArray()
        stream = QDataStream(reply, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_5_7)
        stream.writeUInt16(0)
        stream.writeQString(action)
        stream.writeQString(room)
        stream << date
        stream.device().seek(0)
        stream.writeUInt16(reply.size() - SIZEOF_UINT16)
        socket.write(reply)

class TcpServer(QTcpServer):
    def __init__(self):
        super(TcpServer, self).__init__()

    def incomingConnection(self, socketId):
        thread = tcpThread(socketId, self)
        thread.finished.connect(thread.deleteLater)
        thread.start()

